import fs from 'fs-extra'
import path from 'path'
import { spawn } from 'child_process'
import { fileURLToPath } from 'url'
import AdmZip from 'adm-zip'
import tar from 'tar-stream'
import { createReadStream, createWriteStream } from 'fs'
import zlib from 'zlib'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// 支持的压缩文件扩展名
const SUPPORTED_EXTENSIONS = ['.zip', '.tgz', '.tar.gz', '.rar', '.7z']

/**
 * 获取 product 文件夹中已存在的最大编号
 */
async function getExistingProductCount() {
  const productPath = path.join(__dirname, 'product')

  try {
    await fs.ensureDir(productPath)
    const folders = await fs.readdir(productPath)

    const productFolders = folders.filter(folder => {
      return folder.startsWith('product_') && /^product_\d+$/.test(folder)
    })

    if (productFolders.length === 0) {
      console.log('No existing product folders found, starting from 1')
      return 0
    }

    const numbers = productFolders.map(folder => {
      const match = folder.match(/^product_(\d+)$/)
      return match ? parseInt(match[1]) : 0
    })

    const maxNumber = Math.max(...numbers)
    console.log(`Found existing product folders up to product_${maxNumber}`)
    return maxNumber
  } catch (error) {
    console.error('Error reading product folder:', error.message)
    return 0
  }
}

/**
 * 获取 dowload_zip 文件夹中需要解压的文件数量
 */
async function getZipFilesCount() {
  const downloadZipPath = path.join(__dirname, 'dowload_zip')

  try {
    const files = await fs.readdir(downloadZipPath)
    const zipFiles = files.filter(file => {
      const ext = path.extname(file).toLowerCase()
      return SUPPORTED_EXTENSIONS.includes(ext) || file.endsWith('.tar.gz')
    })

    console.log(`Found ${zipFiles.length} compressed files in dowload_zip:`)
    zipFiles.forEach((file, index) => {
      console.log(`  ${index + 1}. ${file}`)
    })

    return { count: zipFiles.length, files: zipFiles }
  } catch (error) {
    console.error('Error reading dowload_zip folder:', error.message)
    return { count: 0, files: [] }
  }
}

/**
 * 调用 create_product.js 创建产品文件夹
 */
async function createProductFolders(count, startNumber) {
  return new Promise((resolve, reject) => {
    console.log(`\nCreating ${count} product folders starting from product_${startNumber + 1}...`)

    const createProcess = spawn('node', ['create_product.js'], {
      stdio: ['pipe', 'inherit', 'inherit'],
      cwd: __dirname
    })

    // 向 create_product.js 发送文件数量和起始编号
    createProcess.stdin.write(`${count}\n`)
    createProcess.stdin.write(`${startNumber}\n`)
    createProcess.stdin.end()

    createProcess.on('close', (code) => {
      if (code === 0) {
        console.log('Product folders created successfully!')
        resolve()
      } else {
        reject(new Error(`create_product.js exited with code ${code}`))
      }
    })

    createProcess.on('error', (error) => {
      reject(new Error(`Failed to start create_product.js: ${error.message}`))
    })
  })
}

/**
 * 使用 JavaScript 库解压 ZIP 文件
 */
async function extractZipFile(filePath, extractPath) {
  const zip = new AdmZip(filePath)
  await fs.ensureDir(extractPath)

  return new Promise((resolve, reject) => {
    try {
      zip.extractAllTo(extractPath, true)
      resolve()
    } catch (error) {
      reject(error)
    }
  })
}

/**
 * 使用 JavaScript 库解压 TGZ/TAR.GZ 文件
 */
async function extractTgzFile(filePath, extractPath) {
  await fs.ensureDir(extractPath)

  return new Promise((resolve, reject) => {
    const extract = tar.extract()

    extract.on('entry', async (header, stream, next) => {
      try {
        const entryPath = path.join(extractPath, header.name)

        if (header.type === 'directory') {
          await fs.ensureDir(entryPath)
          stream.resume()
          next()
        } else if (header.type === 'file') {
          await fs.ensureDir(path.dirname(entryPath))
          const writeStream = createWriteStream(entryPath)

          stream.pipe(writeStream)
          stream.on('end', () => {
            next()
          })
          stream.on('error', (err) => {
            reject(err)
          })
        } else {
          stream.resume()
          next()
        }
      } catch (error) {
        reject(error)
      }
    })

    extract.on('finish', () => {
      resolve()
    })

    extract.on('error', (error) => {
      reject(error)
    })

    // 创建读取流并通过 gzip 解压
    const readStream = createReadStream(filePath)
    readStream.pipe(zlib.createGunzip()).pipe(extract)
  })
}

/**
 * 解压文件到指定目录 (使用 JavaScript 库)
 */
async function extractFile(filePath, extractPath) {
  const fileName = path.basename(filePath)
  const ext = path.extname(fileName).toLowerCase()

  console.log(`📦 Extracting ${fileName} to ${extractPath}...`)

  try {
    await fs.ensureDir(extractPath)

    if (ext === '.zip') {
      await extractZipFile(filePath, extractPath)
      console.log(`✅ Successfully extracted ${fileName}`)
    } else if (ext === '.tgz' || fileName.endsWith('.tar.gz')) {
      await extractTgzFile(filePath, extractPath)
      console.log(`✅ Successfully extracted ${fileName}`)
    } else {
      throw new Error(`Unsupported file format: ${ext}`)
    }
  } catch (error) {
    console.error(`❌ Error extracting ${fileName}:`, error.message)
    throw error
  }
}

/**
 * 复制解压后的内容到产品文件夹
 */
async function copyExtractedContent(tempExtractPath, productFolderPath) {
  try {
    const items = await fs.readdir(tempExtractPath)

    for (const item of items) {
      const sourcePath = path.join(tempExtractPath, item)
      const destPath = path.join(productFolderPath, item)

      await fs.copy(sourcePath, destPath, { overwrite: true })
      console.log(`Copied ${item} to ${path.basename(productFolderPath)}`)
    }

    // 确保 utils 文件夹存在（如果被覆盖了就重新复制）
    await ensureUtilsFolder(productFolderPath)
  } catch (error) {
    console.error(`Error copying content to ${productFolderPath}:`, error.message)
    throw error
  }
}

/**
 * 确保产品文件夹中存在 utils 文件夹
 */
async function ensureUtilsFolder(productFolderPath) {
  try {
    const utilsSourcePath = path.join(__dirname, 'utils')
    const utilsDestPath = path.join(productFolderPath, 'utils')

    // 检查源 utils 文件夹是否存在
    const utilsExists = await fs.pathExists(utilsSourcePath)
    if (!utilsExists) {
      console.log('Warning: utils folder not found in current directory')
      return
    }

    // 检查目标 utils 文件夹是否存在
    const targetUtilsExists = await fs.pathExists(utilsDestPath)
    if (!targetUtilsExists) {
      await fs.copy(utilsSourcePath, utilsDestPath)
      console.log(`✓ Copied utils folder to ${path.basename(productFolderPath)}`)
    } else {
      console.log(`✓ Utils folder already exists in ${path.basename(productFolderPath)}`)
    }
  } catch (error) {
    console.error(`Error ensuring utils folder in ${productFolderPath}:`, error.message)
  }
}

/**
 * 主函数
 */
async function main() {
  try {
    console.log('=== Starting automated product creation and extraction ===\n')

    // 1. 检查现有的 product 文件夹数量
    const existingCount = await getExistingProductCount()

    // 2. 查询 dowload_zip 中的压缩文件数量
    const { count, files } = await getZipFilesCount()

    if (count === 0) {
      console.log('No compressed files found in dowload_zip folder.')
      return
    }

    // 3. 调用 create_product.js 创建产品文件夹
    await createProductFolders(count, existingCount)

    // 3. 解压文件并复制到对应的产品文件夹
    console.log('\n=== Starting extraction and copying process ===\n')

    const downloadZipPath = path.join(__dirname, 'dowload_zip')
    const productPath = path.join(__dirname, 'product')
    const tempPath = path.join(__dirname, 'temp_extract')

    for (let i = 0; i < files.length; i++) {
      const fileName = files[i]
      const filePath = path.join(downloadZipPath, fileName)
      const productNumber = existingCount + i + 1
      const productFolderName = `product_${productNumber}`
      const productFolderPath = path.join(productPath, productFolderName)
      const tempExtractPath = path.join(tempPath, `extract_${productNumber}`)

      try {
        console.log(`\n--- Processing ${fileName} (${i + 1}/${files.length}) ---`)

        // 解压到临时目录
        await extractFile(filePath, tempExtractPath)

        // 复制到对应的产品文件夹
        await copyExtractedContent(tempExtractPath, productFolderPath)

        // 删除原始压缩文件
        await fs.remove(filePath)
        console.log(`🗑️ Deleted original file: ${fileName}`)

        console.log(`✓ Successfully processed ${fileName} -> ${productFolderName}`)

      } catch (error) {
        console.error(`✗ Failed to process ${fileName}:`, error.message)
        // 继续处理下一个文件
      }
    }

    // 清理临时目录
    try {
      await fs.remove(tempPath)
      console.log('\n✓ Cleaned up temporary extraction directory')
    } catch (error) {
      console.warn('Warning: Failed to clean up temporary directory:', error.message)
    }

    console.log('\n=== Process completed! ===')
    console.log(`Processed ${files.length} files and created ${count} product folders.`)
    console.log('🗑️ All original compressed files have been deleted from dowload_zip folder.')

  } catch (error) {
    console.error('Error in main process:', error.message)
    process.exit(1)
  }
}

// 运行主函数
main()